/*
 * Copyright (c) [2019] Zhang Yansen.All rights reserved.
 *
 * xrc-form2 is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

import React from 'react'
import PropTypes from 'prop-types'
import { Form, Button } from 'antd'
import XItem from './Item'
import { isFunction } from './utils'

const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 8 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 16 },
  },
}

class XForm extends React.PureComponent {
  formRef = React.createRef()

  state = {
    submitting: false,
  }

  toggleSubmitting = (submitting) => {
    this.setState({ submitting })
  }

  handleSubmit = values => {
    const { submitting } = this.state
    if (submitting) return

    const { onSubmit } = this.props
    if (isFunction(onSubmit)) {
      onSubmit(values, this.toggleSubmitting)
    }
  }

  handleError = errors => {
    const { onError } = this.props
    this.toggleSubmitting(false)

    this.formRef.current.scrollToField(errors.errorFields[0].name);

    if (isFunction(onError)) {
      onError(errors)
    } else {
      window.console.error(errors)
    }
  }

  handleCancel = e => {
    e.preventDefault();

    if (isFunction(this.props.onCancel)) {
      this.props.onCancel()
    }
  }


  renderFooter = () => {
    return (
      <XItem label=" " colon={false}>
        <Button htmlType="submit" loading={this.state.submitting} type="primary">提交</Button>
        <Button htmlType="button" onClick={this.handleCancel} style={{ marginLeft: '48px' }}>取消</Button>
      </XItem>
    )
  }

  render () {
    const { fields = [], footer, children, form: custForm, ...formProps } = this.props;
    const form = custForm || this.formRef.current

    let initialValues = {}

    const wrapedFields = fields.map((field) => {
      if (field.name) {
        initialValues = {
          ...initialValues,
          [`${field.name}`]: field.value,
        }
      }

      return {
        ...field,
        form,
      }
    })

    return (
      <Form
        ref={this.formRef}
        initialValues={initialValues}
        {...formItemLayout}
        {...formProps}
        form={form}
        onFinish={this.handleSubmit}
        onFinishFailed={this.handleError}
      >
        {wrapedFields.map((x, i) => <XItem key={`itm-${i}`} {...x} />)}
        {children}
        {footer === null ? null : (footer || this.renderFooter())}
      </Form>
    );
  }
}

XForm.useForm = Form.useForm
XForm.List = Form.List
XForm.Provider = Form.Provider

XForm.propTypes = {
  fields: PropTypes.array.isRequired,
  footer: PropTypes.node,
  onSubmit: PropTypes.func,
  onError: PropTypes.func,
  onCancel: PropTypes.func,
}

export default XForm
